#pragma once
#include <cstddef>
#include <iostream>
#include <istream>
#include <ostream>
class string
{
    friend std::ostream &operator<<(std::ostream &cout, const string &s);
    friend std::istream &operator>>(std::istream &cin, string &str);

public:
    typedef char *iterator;
    static const size_t npos = static_cast<size_t>(-1);
    string() = default;
    string(const string &str);
    string(const string &str, size_t pos, size_t len = npos);
    string(const char *str);
    string(const char *str, size_t n);
    string(size_t n, char c);
    void push_back(char c);
    string &operator+=(char c);
    const char *data() const;
    void append(const char *str);
    void append(const string &str);
    void append(const char *s, size_t n);
    void append(size_t n, char c);
    void reserve(size_t n);
    string &operator+=(const char *str);
    char &operator[](size_t index);
    const char &operator[](size_t index) const;
    bool operator<(const string &s) const;
    bool operator<=(const string &s) const;
    bool operator>(const string &s) const;
    bool operator>=(const string &s) const;
    bool operator==(const string &s) const;
    bool operator!=(const string &s) const;
    string &operator=(const string &str);
    string &operator=(const char *str);
    string &operator=(char c);
    void resize(size_t n, char c = '\0');
    void pop_back();
    size_t size() const;
    size_t capacity() const;
    bool empty() const;
    void clear();
    string &insert(size_t pos, const string &str);
    string &insert(size_t pos, const char *str);
    string &erase(size_t pos = 0, size_t len = npos);
    string substr(size_t pos = 0, size_t len = npos) const;
    const char *c_str() const;
    void swap(string &s);
    size_t find(const char *s, size_t pos = 0) const;
    size_t find(char c, size_t pos = 0) const;
    ~string();

private:
    char *str_ = nullptr;
    size_t capacity_ = 0;
    size_t size_ = 0;
};
